#include "linkstack.h"

extern func_linklist fun_linklist;
// #ifndef null
// define null NULL
// #endif

/**
 * 功 能：
 *      创建一个栈
 * 参 数：
 *      无
 * 返回值：
 *      成功：操作句柄
 *      失败：NULL
 **/
LinkStack *LinkStack_Create(void)
{
    return fun_linklist.create();
}

/**
 * 功 能：
 *      插入元素，压栈
 * 参 数：
 *      Stack：要操作的栈
 *      node : 要插入的元素，栈的业务节点
 * 返回值：
 *      成功：0
 *      失败：-1
 **/
int LinkStack_Push(LinkStack *Stack, LinkStackNode *node)
{
    if (Stack == NULL || node == NULL)
        return -1;
    TLinkStackNode *temp = NULL;
    int ret = 0;
    temp = (TLinkStackNode *)malloc(sizeof(TLinkStackNode));
    if (temp == NULL)
        return -1;

    memset(temp, 0, sizeof(TLinkStackNode));

    temp->item = node;

    ret = fun_linklist.insert(Stack, (LinkListNode *)temp, 0);
    if (ret != 0 && temp != NULL)
        free(temp);

    return ret;
}

/**
 * 功 能：
 *      弹出栈元素
 * 参 数：
 *      Stack：要操作的栈
 * 返回值：
 *      成功：删除后的元素
 *      失败：NULL
 **/
LinkStackNode *LinkStack_Pop(LinkStack *Stack)
{
    if (Stack == NULL)
        return NULL;
    LinkStackNode *item = NULL;
    TLinkStackNode *temp = NULL;
    temp = (TLinkStackNode *)fun_linklist.delete(Stack, 0);
    if (temp == NULL)
        return NULL;

    // 吧线性表的业务节点转换成栈的业务节点
    item = temp->item;
    // 在 insert 的时候malloc的内存需要free掉
    free(temp);

    return item;
}

/**
 * 功 能：
 *      清空一个栈
 * 参 数：
 *      Stack：要操作的栈
 * 返回值：
 *      成功：0
 *      失败：-1
 **/
// 涉及到栈的元素声明周期的处理
// 所有入栈的节点都是通过mallo静态申请的，那么想要清空栈的时候，需要将malloc的节点free掉
// 所以需要将栈中元素全都pop掉，并且free节点的内存
int LinkStack_Clear(LinkStack *Stack)
{
    if (Stack == NULL)
        return -1;

    while (fun_linklist.length(Stack) > 0)
    {
        LinkStackNode *temp = LinkStack_Pop(Stack);
        if (temp == NULL)
        {
            return -1;
        }
    }
    return 0;
}

/**
 * 功 能：
 *      销毁一个栈
 * 参 数：
 *      Stack：要操作的栈
 * 返回值：
 *      成功：0
 *      失败：-1
 **/
int LinkStack_Destory(LinkStack *Stack)
{
    LinkStack_Clear(Stack);
    return fun_linklist.destory(&Stack);
}

/**
 * 功 能：
 *      获取栈的长度
 * 参 数：
 *      Stack：要操作的栈
 * 返回值：
 *      成功：栈的长度
 *      失败：-1
 **/
int LinkStack_Length(LinkStack *Stack)
{
    return fun_linklist.length(Stack);
}

/**
 * 功 能：
 *      获取栈顶的元素
 * 参 数：
 *      Stack：要操作的栈
 * 返回值：
 *      成功：操作句柄
 *      失败：NULL
 **/
LinkStackNode *LinkStack_Get(LinkStack *Stack)
{
    if (Stack == NULL)
        return NULL;
    TLinkStackNode *temp = NULL;
    temp = (TLinkStackNode *)fun_linklist.get(Stack, 0);

    if (temp == NULL)
        return NULL;

    return temp->item;
}

func_LinkStack fun_LinkStack = {
    LinkStack_Create,
    LinkStack_Destory,
    LinkStack_Clear,
    LinkStack_Length,
    LinkStack_Push,
    LinkStack_Get,
    LinkStack_Pop};
